package com.xjrsoft.module.customerTwo.EMP.settlement.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.core.constant.RedisKeyConstants;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.entity.TElectricCheckinLog;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.mapper.TElectricCheckinLogMapper;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.service.ITElectricCheckinLogService;
import com.xjrsoft.module.customerTwo.EMP.dormitory_room.entity.TDormitoryRoom;
import com.xjrsoft.module.customerTwo.EMP.dormitory_room.service.ITDormitoryRoomService;
import com.xjrsoft.module.customerTwo.EMP.repair.entity.TElectricRepair;
import com.xjrsoft.module.customerTwo.EMP.repair.mapper.TElectricRepairMapper;
import com.xjrsoft.module.customerTwo.EMP.repair.service.ITElectricRepairService;
import com.xjrsoft.module.customerTwo.EMP.settlement.entity.TElectricCheckoutSettlement;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.xjrsoft.core.tool.utils.CollectionUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import com.xjrsoft.module.customerTwo.EMP.settlement.entity.TElectricCheckoutSettlementDetails;
import com.xjrsoft.module.customerTwo.EMP.settlement.entity.TElectricCheckoutSettlementTools;
import com.xjrsoft.module.customerTwo.EMP.settlement.service.ITElectricCheckoutSettlementDetailsService;
import com.xjrsoft.module.customerTwo.EMP.settlement.dto.TElectricCheckoutSettlementListDto;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xjrsoft.common.page.ConventPage;
import java.util.List;
import java.util.Objects;

import com.xjrsoft.module.customerTwo.EMP.settlement.mapper.TElectricCheckoutSettlementMapper;
import com.xjrsoft.module.customerTwo.EMP.settlement.service.ITElectricCheckoutSettlementService;
import com.xjrsoft.core.mp.base.BaseService;
import com.xjrsoft.core.tool.utils.Func;
import com.xjrsoft.module.customerTwo.EMP.settlement.service.ITElectricCheckoutSettlementToolsService;
import lombok.AllArgsConstructor;
import lombok.experimental.var;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 *  服务实现类
 *
 * @author lisen
 * @since 2023-08-04
 */
@Service
@AllArgsConstructor
public class TElectricCheckoutSettlementServiceImpl extends BaseService<TElectricCheckoutSettlementMapper, TElectricCheckoutSettlement> implements ITElectricCheckoutSettlementService {

	private ITElectricCheckoutSettlementDetailsService tElectricCheckoutSettlementDetailsService;
	private ITElectricCheckoutSettlementToolsService tElectricCheckoutSettlementToolsService;
	@Resource
	ITElectricRepairService repairService;

	@Resource
	TElectricRepairMapper repairMapper;

	@Resource
	ITElectricCheckinLogService CheckinLogService;

	@Resource
	TElectricCheckinLogMapper tElectricCheckinLogMapper;

	@Resource
	ITDormitoryRoomService roomService;

	@Resource
	RedisTemplate<String,Object> redisTemplate;

	@Override
	public IPage<TElectricCheckoutSettlement> getPageList(TElectricCheckoutSettlementListDto pageListDto) {
		Wrapper<TElectricCheckoutSettlement> wrapper = Wrappers.<TElectricCheckoutSettlement>query().lambda()
				.like(!StringUtil.isEmpty(pageListDto.getIdentify_name()), TElectricCheckoutSettlement::getIdentifyName, pageListDto.getIdentify_name())
				.like(!StringUtil.isEmpty(pageListDto.getIdentify_id()), TElectricCheckoutSettlement::getIdentifyId, pageListDto.getIdentify_id())
				.like(!StringUtil.isEmpty(pageListDto.getDivision()), TElectricCheckoutSettlement::getDivision, pageListDto.getDivision())
				.ge(!StringUtil.isEmpty(pageListDto.getCheckin_date_Start()), TElectricCheckoutSettlement::getCheckinDate, pageListDto.getCheckin_date_Start())
				.like(!StringUtil.isEmpty(pageListDto.getRoomNumber()), TElectricCheckoutSettlement::getRoomNumber, pageListDto.getRoomNumber())
				.le(!StringUtil.isEmpty(pageListDto.getCheckin_date_End()), TElectricCheckoutSettlement::getCheckinDate, pageListDto.getCheckin_date_End())
				.ge(!StringUtil.isEmpty(pageListDto.getCheckout_date_Start()), TElectricCheckoutSettlement::getCheckoutDate, pageListDto.getCheckout_date_Start())
				.le(!StringUtil.isEmpty(pageListDto.getCheckout_date_End()), TElectricCheckoutSettlement::getCheckoutDate, pageListDto.getCheckout_date_End())
				.like(!StringUtil.isEmpty(pageListDto.getWorkshop()), TElectricCheckoutSettlement::getWorkshop, pageListDto.getWorkshop());
		return this.page(ConventPage.getPage(pageListDto), wrapper);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean addTElectricCheckoutSettlement(TElectricCheckoutSettlement tElectricCheckoutSettlement, List<TElectricCheckoutSettlementDetails> tElectricCheckoutSettlementDetailsList,List<TElectricCheckoutSettlementTools> tElectricCheckoutSettlementToolsList) throws Exception {
		String tElectricCheckoutSettlementId = IdWorker.get32UUID();
		tElectricCheckoutSettlement.setFid(tElectricCheckoutSettlementId);
		tElectricCheckoutSettlementDetailsList.forEach(tElectricCheckoutSettlementDetails -> tElectricCheckoutSettlementDetails.setSettlementId(tElectricCheckoutSettlementId));
		tElectricCheckoutSettlementToolsList.forEach(tElectricCheckoutSettlementTools -> tElectricCheckoutSettlementTools.setSettlementId(tElectricCheckoutSettlementId));
		tElectricCheckoutSettlementToolsList.forEach(tElectricCheckoutSettlementTools -> tElectricCheckoutSettlementTools.setFid(IdWorker.get32UUID()));
		LocalDateTime date =null;
		for(TElectricCheckoutSettlementDetails details:tElectricCheckoutSettlementDetailsList){
			if(details.getIteams().equals("维修赔偿")){
				date=details.getCheckoutDate();
			}
		}
		List<TElectricRepair> list = repairService.getByIdentity(tElectricCheckoutSettlement.getIdentifyId());
		if(list.size()>0&&date!=null){
			list.removeIf(l -> Objects.equals(l.getIspayed(), 1));
			for(TElectricRepair l:list){
				l.setIspayed(1);
				l.setPayDate(date);
			}
			repairService.updateBatchById(list);
		}
		return CheckinLogService.checkOut(tElectricCheckoutSettlement.getCheckinId(),tElectricCheckoutSettlement.getCheckoutDate()) &&  this.save(tElectricCheckoutSettlement) && tElectricCheckoutSettlementDetailsService.saveBatch(tElectricCheckoutSettlementDetailsList) && tElectricCheckoutSettlementToolsService.saveBatch(tElectricCheckoutSettlementToolsList);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deprecated(String id) throws Exception {
		TElectricCheckoutSettlement settlement = getById(id);
		settlement.setIsDeprecated(1);
		LocalDateTime date =null;
		List<TElectricRepair> list = repairService.getByIdentity(settlement.getIdentifyId());
		//清空赔偿情况
		if(!list.isEmpty()){
			for(TElectricRepair l:list){
				UpdateWrapper<TElectricRepair> wrappers = new UpdateWrapper<>();
				l.setIspayed(0);
				l.setPayDate(date);
				wrappers.set("pay_date", null).set("ispayed",0).eq("fid",l.getFid());
				repairMapper.update(null,wrappers);
			}
		}

		TElectricCheckinLog checkinLog = CheckinLogService.getById(settlement.getCheckinId());
		checkinLog.setIsCheckout(0);
		ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
		//夫妻房的问题
		TDormitoryRoom room = roomService.getByRoomNumber(checkinLog.getRoomNumber());
		if("4".equals(room.getRoomType())&&room.getUsedBedNumber().equals(1)){
			room.setUsedBedNumber(2);
			//设置成未退宿，清空退宿日期
			UpdateWrapper<TElectricCheckinLog> wrapper = new UpdateWrapper<>();
			wrapper.set("checkout_date", null).eq("fid",settlement.getCheckinId());
			//无床位
			tElectricCheckinLogMapper.update(null,wrapper);
			return this.updateById(settlement)&&roomService.updateById(room);
		}
		if(valueOperations.get(RedisKeyConstants.CACHE_ROOM_LEFT+checkinLog.getRoomNumber())!=null){

			//床位大于1
			if((Integer)valueOperations.get(RedisKeyConstants.CACHE_ROOM_LEFT+checkinLog.getRoomNumber())>1){
				redisTemplate.opsForValue().decrement(RedisKeyConstants.CACHE_ROOM_LEFT+checkinLog.getRoomNumber());
				CheckinLogService.updateById(checkinLog);
				return roomService.upDateUsedRoomByRoomNum(checkinLog.getRoomNumber(),1);
			}
			//等于1
			redisTemplate.delete(RedisKeyConstants.CACHE_ROOM_LEFT+checkinLog.getRoomNumber());
			CheckinLogService.updateById(checkinLog);
			roomService.upDateUsedRoomByRoomNum(checkinLog.getRoomNumber(),1);
		}

		//设置成未退宿，清空退宿日期
		UpdateWrapper<TElectricCheckinLog> wrapper = new UpdateWrapper<>();
		wrapper.set("checkout_date", null).eq("fid",settlement.getCheckinId());
		//无床位
		tElectricCheckinLogMapper.update(null,wrapper);
		return this.updateById(settlement);
	}


	@Override
	public boolean updateTElectricCheckoutSettlement(String id, TElectricCheckoutSettlement tElectricCheckoutSettlement, List<TElectricCheckoutSettlementDetails> tElectricCheckoutSettlementDetailsList,List<TElectricCheckoutSettlementTools> tElectricCheckoutSettlementToolsList) {
		tElectricCheckoutSettlement.setFid(id);

		List<String> tElectricCheckoutSettlementDetailsIdList = new ArrayList<>();
		for (TElectricCheckoutSettlementDetails tElectricCheckoutSettlementDetails : tElectricCheckoutSettlementDetailsList) {
			String tElectricCheckoutSettlementDetailsId = tElectricCheckoutSettlementDetails.getFid();
			if (StringUtil.isEmpty(tElectricCheckoutSettlementDetailsId)) {
				tElectricCheckoutSettlementDetails.setSettlementId(id);
			} else {
				tElectricCheckoutSettlementDetailsIdList.add(tElectricCheckoutSettlementDetailsId);
			}
		}
		if (CollectionUtil.isNotEmpty(tElectricCheckoutSettlementDetailsIdList)) {
			tElectricCheckoutSettlementDetailsService.remove(Wrappers.<TElectricCheckoutSettlementDetails>query().lambda()
					.notIn(TElectricCheckoutSettlementDetails::getFid, tElectricCheckoutSettlementDetailsIdList)
					.eq(TElectricCheckoutSettlementDetails::getSettlementId, id));
		}
		tElectricCheckoutSettlementDetailsService.saveOrUpdateBatch(tElectricCheckoutSettlementDetailsList);

		List<String> tElectricCheckoutSettlementToolsIdList = new ArrayList<>();
		for (TElectricCheckoutSettlementTools tElectricCheckoutSettlementTools : tElectricCheckoutSettlementToolsList) {
			String tElectricCheckoutSettlementToolsId = tElectricCheckoutSettlementTools.getFid();
			if (StringUtil.isEmpty(tElectricCheckoutSettlementToolsId)) {
				tElectricCheckoutSettlementTools.setSettlementId(id);
			} else {
				tElectricCheckoutSettlementToolsIdList.add(tElectricCheckoutSettlementToolsId);
			}
		}
		if (CollectionUtil.isNotEmpty(tElectricCheckoutSettlementToolsIdList)) {
			tElectricCheckoutSettlementToolsService.remove(Wrappers.<TElectricCheckoutSettlementTools>query().lambda()
					.notIn(TElectricCheckoutSettlementTools::getFid, tElectricCheckoutSettlementToolsIdList)
					.eq(TElectricCheckoutSettlementTools::getSettlementId, id));
		}
		tElectricCheckoutSettlementToolsService.saveOrUpdateBatch(tElectricCheckoutSettlementToolsList);
		return this.updateById(tElectricCheckoutSettlement);
	}

	@Override
	public boolean delete(String ids) {
		List<String> idList = Func.toStrList(ids);
		if (this.removeByIds(idList)) {
			tElectricCheckoutSettlementDetailsService.remove(Wrappers.<TElectricCheckoutSettlementDetails>query().lambda().in(TElectricCheckoutSettlementDetails::getSettlementId, ids));
			tElectricCheckoutSettlementToolsService.remove(Wrappers.<TElectricCheckoutSettlementTools>query().lambda().in(TElectricCheckoutSettlementTools::getSettlementId, ids));
			return true;
		}
		return false;
	}

	@Override
	public List<TElectricCheckoutSettlementDetails> getTElectricCheckoutSettlementDetailsByParentId(String parentId){
		Wrapper wrapper = Wrappers.<TElectricCheckoutSettlementDetails>query().lambda().eq(TElectricCheckoutSettlementDetails::getSettlementId, parentId);
		return tElectricCheckoutSettlementDetailsService.list(wrapper);
	}

	@Override
	public List<TElectricCheckoutSettlementTools> getTElectricCheckoutSettlementToolsByParentId(String parentId){
		Wrapper wrapper = Wrappers.<TElectricCheckoutSettlementTools>query().lambda().eq(TElectricCheckoutSettlementTools::getSettlementId, parentId);
		return tElectricCheckoutSettlementToolsService.list(wrapper);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean settle(String id){
		TElectricCheckoutSettlement tElectricCheckoutSettlement = getById(id);
		if(tElectricCheckoutSettlement.getIssettled()==0){
			tElectricCheckoutSettlement.setIssettled(1);
			List<TElectricRepair> list = repairService.getByIdentity(tElectricCheckoutSettlement.getIdentifyId());
			list.removeIf(l -> Objects.equals(l.getIspayed(), 1));
			for(TElectricRepair l:list){
				l.setIspayed(1);
			}
			boolean isSuccess = this.updateById(tElectricCheckoutSettlement);
			if(isSuccess){
				if(list.size()>0){
					return repairService.updateBatchById(list);
				}
				return isSuccess;
			}
			return false;
		}
		return false;
	}

	@Override
	public boolean confirm(String id){
		TElectricCheckoutSettlement tElectricCheckoutSettlement = getById(id);
		if(tElectricCheckoutSettlement.getIslocked()==0){
			tElectricCheckoutSettlement.setIslocked(1);
			return updateById(tElectricCheckoutSettlement);
		}
		tElectricCheckoutSettlement.setIslocked(0);
		return updateById(tElectricCheckoutSettlement);
	}
}